home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung CD 2 (Tewi)(1994).iso
/
doc
/
ems
/
disk3
/
emmlib.mac
< prev
next >
Wrap
Text File
|
1989-11-29
|
27KB
|
475 lines
;-----------------------------------------------------------------------------;
; Macro Name: MULT arg, val ;
; Author: W J Krueger ;
; Date: 5/12/87 ;
; Description: If val is 0 or a power of two this macro multiplies ;
; arg by val. ;
;-----------------------------------------------------------------------------;
MULT MACRO arg, val
bit_pat = (val)
bit_cnt = ((val) AND 1)
IF ((bit_pat) EQ 0)
MOV arg, 0
ELSEIF ((bit_pat) NE 1)
REPT 15
IF ((bit_cnt) EQ 0)
SHL arg, 1
ENDIF
bit_pat = (bit_pat) SHR 1
IF ((bit_pat) AND 1)
bit_cnt = (bit_cnt) + 1
ENDIF
ENDM
ENDIF
IF ((bit_cnt) GT 1)
IF2
.ERR The MULT macro cannot multiply &arg by &val. Use a MUL instruction.
%OUT The MULT macro cannot multiply &arg by &val. Use a MUL instruction.
ENDIF
ENDIF
ENDM
PAGE
;----------------------GENERIC MOVE INSTRUCTION PARSER------------------------;
; ;
; This macro decomposes the destination and source arguments into "left" ;
; and "right" components for each argument. The "left" and "right" ;
; argument halves of the destination and source arguments are the text ;
; strings that appear to the left or the right of a colon (:). So, ;
; a destination or source argument that was formatted as AX:BX would ;
; be separated into left and right components which were equal to AX ;
; and BX respectively. The example used registers but any text string ;
; (or strings) can be substituted. For example: ES:word_array[4*3] is ;
; a perfectly acceptable construct. However, if you want to redefine ;
; the type of one of the arguments (i.e. reference the word_array as a byte ;
; array), then you could use ES:<BYTE PTR word_array[12]>. The point being ;
; that this is a macro and requires text separated by spaces to be included ;
; inside <> so that the text is considered as a single string. ;
; ;
;------------------------------VALID TOKENS-----------------------------------;
; ;
; N...nul...null argument D...dat...data argument ;
; S...seg...segment argument R...reg...register argument ;
; O...off...offset argument C...con...constant argument ;
; A...adr...address argument P...con_dat...constant assoc ;
; with data (pointer) ;
; ;
;-----------------------INVALID TOKEN COMBINATIONS----------------------------;
; ;
; nul:adr seg:con off:adr adr:adr dat:adr reg:adr con:adr ;
; nul:con seg:seg off:con adr:con dat:con reg:con con:dat ;
; nul:dat off:dat adr:dat dat:dat reg:dat con:off ;
; nul:nul off:off adr:off dat:off reg:off con:reg ;
; nul:off off:reg adr:reg dat:reg reg:seg con:seg ;
; nul:reg off:seg adr:seg dat:seg ;
; nul:seg ;
;------------------------VALID TOKEN COMBINATIONS-----------------------------;
; ;
; seg:adr off:nul adr:nul dat:nul reg:nul con:con ;
; seg:dat reg:reg con:nul ;
; seg:nul ;
; seg:off ;
; seg:reg ;
; ;
;--------------------INVALID TOKEN COMBINATIONS & PAIRINGS--------------------;
; ;
; seg:nul, con:con reg:nul, con:con con:con, adr:nul ;
; seg:nul, reg:reg reg:nul, reg:reg con:con, con:con ;
; seg:nul, seg:reg reg:nul, seg:reg con:con, con:nul ;
; seg:reg, con:nul reg:reg, con:nul con:con, dat:nul ;
; seg:reg, reg:nul reg:reg, reg:nul con:con, off:nul ;
; seg:reg, seg:nul reg:reg, seg:nul con:con, reg:nul ;
; con:con, reg:reg ;
; con:con, seg:adr ;
; con:con, seg:dat ;
; con:con, seg:nul ;
; con:con, seg:off ;
; con:con, seg:reg ;
; con:nul, adr:nul ;
; con:nul, con:con ;
; con:nul, con:nul ;
; con:nul, dat:nul ;
; con:nul, off:nul ;
; con:nul, reg:nul ;
; con:nul, reg:reg ;
; con:nul, seg:adr ;
; con:nul, seg:dat ;
; con:nul, seg:nul ;
; con:nul, seg:off ;
; con:nul, seg:reg ;
; ;
;-----------------AMBIGUOUS TOKEN COMBINATIONS & PAIRINGS---------------------;
; (due to ambiguous size) ;
; ;
; seg:adr, adr:nul off:nul, adr:nul adr:nul, adr:nul dat:nul, adr:nul ;
; seg:adr, dat:nul off:nul, dat:nul adr:nul, dat:nul dat:nul, dat:nul ;
; seg:adr, off:nul off:nul, off:nul adr:nul, off:nul dat:nul, off:nul ;
; seg:adr, seg:adr off:nul, seg:adr adr:nul, seg:adr dat:nul, seg:adr ;
; seg:adr, seg:dat off:nul, seg:dat adr:nul, seg:dat dat:nul, seg:dat ;
; seg:adr, seg:off off:nul, seg:off adr:nul, seg:off dat:nul, seg:off ;
; seg:dat, adr:nul ;
; seg:dat, dat:nul ;
; seg:dat, off:nul ;
; seg:dat, seg:adr ;
; seg:dat, seg:dat ;
; seg:dat, seg:off ;
; seg:off, adr:nul ;
; seg:off, dat:nul ;
; seg:off, off:nul ;
; seg:off, seg:adr ;
; seg:off, seg:dat ;
; seg:off, seg:off ;
; ;
;-----------------------VALID TOKEN COMBINATIONS & PAIRINGS-------------------;
; ;
; seg:nul, seg:nul seg:off, seg:nul seg:adr, seg:nul seg:dat, seg:nul ;
; seg:nul, seg:off seg:off, seg:reg seg:adr, seg:reg seg:dat, seg:reg ;
; seg:nul, seg:adr seg:off, reg:nul seg:adr, reg:nul seg:dat, reg:nul ;
; seg:nul, seg:dat seg:off, reg:reg seg:adr, reg:reg seg:dat, reg:reg ;
; seg:nul, off:nul seg:off, con:nul seg:adr, con:nul seg:dat, con:nul ;
; seg:nul, adr:nul seg:off, con:con seg:adr, con:con seg:dat, con:con ;
; seg:nul, dat:nul ;
; seg:nul, reg:nul ;
; seg:nul, con:nul ;
; ;
; seg:reg, seg:off off:nul, seg:nul adr:nul, seg:nul dat:nul, seg:nul ;
; seg:reg, seg:adr off:nul, seg:reg adr:nul, seg:reg dat:nul, seg:reg ;
; seg:reg, seg:dat off:nul, reg:nul adr:nul, reg:nul dat:nul, reg:nul ;
; seg:reg, seg:reg off:nul, reg:reg adr:nul, reg:reg dat:nul, reg:reg ;
; seg:reg, off:nul off:nul, con:nul adr:nul, con:nul dat:nul, con:nul ;
; seg:reg, adr:nul off:nul, con:con adr:nul, con:con dat:nul, con:con ;
; seg:reg, dat:nul ;
; seg:reg, reg:reg ;
; seg:reg, con:con ;
; ;
; reg:nul, seg:nul reg:reg, seg:off ;
; reg:nul, seg:off reg:reg, seg:adr ;
; reg:nul, seg:adr reg:reg, seg:dat ;
; reg:nul, seg:dat reg:reg, seg:reg ;
; reg:nul, off:nul reg:reg, off:nul ;
; reg:nul, adr:nul reg:reg, adr:nul ;
; reg:nul, dat:nul reg:reg, dat:nul ;
; reg:nul, reg:nul reg:reg, reg:reg ;
; reg:nul, con:nul reg:reg, con:con ;
; ;
;-----------------------------------------------------------------------------;
MOVE MACRO dest, source
;;------------------------------------------------------------------------;
;; destination_source argument type encoding string ;
;;------------------------------------------------------------------------;
PASS = 1
FAIL = 0
OFF_ARG = 20h
DAT_ARG = 22h
CON_ARG = 24h
CON_DAT_ARG = 26h
ADR_ARG = 2Ah
REG_ARG = 30h
NUL_ARG = (0FFh AND -1)
SEG_ARG = (0FFh AND -2)
;;------------------------------------------------------------------------;
;; destination_source argument type encoding string ;
;;------------------------------------------------------------------------;
dest_source_tokens EQU <>
dest_R EQU <>
dest_L EQU <>
source_R EQU <>
source_L EQU <>
dest_R_len = 0
dest_L_len = 0
source_R_len = 0
source_L_len = 0
;;------------------------------------------------------------------------;
;; display message ;
;;------------------------------------------------------------------------;
DISPLAY MACRO _text
IF2
%OUT _text
ENDIF
ENDM
;;------------------------------------------------------------------------;
;; get attributes of arguments ;
;;------------------------------------------------------------------------;
COMPONENTS MACRO arg, arg_L, arg_L_len, arg_R, arg_R_len
i INSTR <&arg>, <:>
arg_R_len = 0
arg_L_len SIZESTR <&arg>
IF (i NE 0)
arg_R_len = arg_L_len-i
arg_L_len = i-1
ENDIF
arg_R SUBSTR <&arg>, i+1, arg_R_len
arg_L SUBSTR <&arg>, 1, arg_L_len
ENDM
;;------------------------------------------------------------------------;
;; strip out text component of an argument ;
;;------------------------------------------------------------------------;
STRIP MACRO arg, stripped_arg, string
i INSTR <&arg>, <&string>
i_len SIZESTR <&string>
IF (i)
stripped_arg SUBSTR <&arg>, i+i_len
ENDIF
ENDM
;;------------------------------------------------------------------------;
;; tokenize arg into an arg type & concat the type into a type string ;
;;------------------------------------------------------------------------;
TOKEN MACRO arg, arg_len
IF (arg_len EQ 0)
dest_source_tokens CATSTR dest_source_tokens, <N>
ELSE
i INSTR <DS ES SS CS >, arg
IF (i)
dest_source_tokens CATSTR dest_source_tokens, <S>
ELSE
i = .TYPE (arg)
IF (i EQ reg_arg)
dest_source_tokens CATSTR dest_source_tokens, <R>
ELSEIF (i EQ off_arg)
dest_source_tokens CATSTR dest_source_tokens, <O>
ELSEIF (i EQ adr_arg)
dest_source_tokens CATSTR dest_source_tokens, <A>
ELSEIF (i EQ dat_arg)
dest_source_tokens CATSTR dest_source_tokens, <D>
ELSEIF (i EQ con_arg)
dest_source_tokens CATSTR dest_source_tokens, <C>
ELSEIF (i EQ con_dat_arg)
dest_source_tokens CATSTR dest_source_tokens, <P>
ELSE
dest_source_tokens CATSTR dest_source_tokens, <?>
ENDIF
ENDIF
ENDIF
ENDM
;;------------------------------------------------------------------------;
;; decompose dest & source arguments into left & right components ;
;;------------------------------------------------------------------------;
COMPONENTS <dest>, <dest_L>, <dest_L_len>, <dest_R>, <dest_R_len>
COMPONENTS <source>, <source_L>, <source_L_len>, <source_R>, <source_R_len>
;;------------------------------------------------------------------------;
;; encode dest & source components into dest & source arg type string ;
;; n = null argument o = offset argument c = constant argument ;
;; s = segment argument a = address argument ;
;; r = register argument d = data argument ;
;;------------------------------------------------------------------------;
TOKEN <dest_L>, <dest_L_len>
TOKEN <dest_R>, <dest_R_len>
TOKEN <source_L>, <source_L_len>
TOKEN <source_R>, <source_R_len>
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:nul, seg:nul ;
;; ;
;; SATISFIED BY: ;
;; PUSH source ;
;; POP dest ;
;;------------------------------------------------------------------------;
i INSTR <SNSN>, dest_source_tokens
IF (i)
PUSH source
POP dest
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:nul, con:nul ;
;; ;
;; SATISFIED BY: ;
;; PUSH AX PUSH source (186/286/386) ;
;; MOV AX, source or POP dest ;
;; MOV dest, AX ;
;; POP AX ;
;;------------------------------------------------------------------------;
i INSTR <SNCN>, dest_source_tokens
IF (i)
IF (@CPU AND 1110b)
PUSH source
POP dest
ELSE
PUSH AX
MOV AX, source
MOV dest, AX
POP AX
ENDIF
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:nul, seg:off seg:adr, seg:nul dat:nul, seg:nul ;
;; seg:nul, seg:adr seg:adr, reg:nul dat:nul, reg:nul ;
;; seg:nul, seg:dat seg:adr, con:nul dat:nul, con:nul ;
;; seg:nul, off:nul seg:dat, seg:nul ;
;; seg:nul, adr:nul seg:dat, reg:nul reg:nul, seg:nul ;
;; seg:nul, dat:nul seg:dat, con:nul reg:nul, seg:off ;
;; seg:nul, reg:nul reg:nul, seg:adr ;
;; off:nul, seg:nul reg:nul, seg:dat ;
;; seg:off, seg:nul off:nul, reg:nul reg:nul, off:nul ;
;; seg:off, reg:nul off:nul, con:nul reg:nul, adr:nul ;
;; seg:off, con:nul reg:nul, dat:nul ;
;; adr:nul, seg:nul reg:nul, reg:nul ;
;; adr:nul, reg:nul reg:nul, con:nul ;
;; adr:nul, con:nul ;
;; ;
;; SATISFIED BY: ;
;; MOV dest, source ;
;;------------------------------------------------------------------------;
i INSTR <SNSO SNSA SNSD SNON SNAN SNDN SNRN SOSN SORN SOCN SASN SARN SACN SDSN SDRN SDCN>, dest_source_tokens
j INSTR <ONSN ONRN ONCN ANSN ANRN ANCN DNSN DNRN DNCN RNSN RNSO RNSA RNSD RNON RNAN RNDN RNRN RNCN>, dest_source_tokens
IF (i+j)
MOV dest, source
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:reg, reg:reg reg:reg, seg:reg ;
;; reg:reg, reg:reg ;
;; reg:reg, con:con ;
;; reg:reg, reg:con ;
;; reg:reg, con:reg ;
;; ;
;; SATISFIED BY: ;
;; MOV dest_Right, source_Right ;
;; MOV dest_Left, source_Left ;
;;------------------------------------------------------------------------;
i INSTR <SRRR RRSR RRRR RRCC RRCR RRRC>, dest_source_tokens
IF (i)
i INSTR <RRCC>, dest_source_tokens
IF (i)
IFIDN <source_R>, <source_L>
MOV dest_R, source_L
MOV dest_L, dest_R
EXITM
ENDIF
ENDIF
MOV dest_R, source_R
MOV dest_L, source_L
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:reg, ptr:nul ;
;; ;
;; SATISFIED BY: ;
;; MOV dest_Right, SEG source ;
;; MOV dest_Left, dest_Right ;
;; MOV dest_Right, OFFSET source ;
;;------------------------------------------------------------------------;
i INSTR <SRPN>, dest_source_tokens
IF (i)
STRIP <source>, source_L, <OFFSET >
MOV dest_R, SEG source_L
MOV dest_L, dest_R
MOV dest_R, OFFSET source_L
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:reg, seg:reg ;
;; seg:reg, con:con ;
;; ;
;; SATISFIED BY: ;
;; MOV dest_Right, source_Left ;
;; MOV dest_Left, dest_Right ;
;; MOV dest_Right, source_Right ;
;;------------------------------------------------------------------------;
i INSTR <SRSR SRCC>, dest_source_tokens
IF (i)
i INSTR <SRCC>, dest_source_tokens
IF (i)
IFIDN <&source_R>, <&source_L>
MOV dest_R, source_L
MOV dest_L, dest_R
EXITM
ENDIF
ENDIF
MOV dest_R, source_L
MOV dest_L, dest_R
MOV dest_R, source_R
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:off, seg:reg seg:dat, seg:reg adr:nul, seg:reg ;
;; seg:off, reg:reg seg:dat, reg:reg adr:nul, reg:reg ;
;; seg:off, con:con seg:dat, con:con adr:nul, con:con ;
;; ;
;; seg:adr, seg:reg off:nul, seg:reg dat:nul, seg:reg ;
;; seg:adr, reg:reg off:nul, reg:reg dat:nul, reg:reg ;
;; seg:adr, con:con off:nul, con:con dat:nul, con:con ;
;; ;
;; SATISFIED BY: ;
;; MOV WORD PTR dest [0], source_Left ;
;; MOV WORD PTR dest [2], source_Right ;
;;------------------------------------------------------------------------;
i INSTR <SOSR SORR SOCC SASR SARR SACC SDSR SDRR SDCC ONSR ONRR ONCC ANSR ANRR ANCC DNSR DNRR DNCC>, dest_source_tokens
IF (i)
MOV WORD PTR dest [0], source_R
MOV WORD PTR dest [2], source_L
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; FORMS: ;
;; seg:reg, seg:off reg:reg, seg:off reg:reg, off:nul ;
;; seg:reg, seg:adr reg:reg, seg:adr reg:reg, adr:nul ;
;; seg:reg, seg:dat reg:reg, seg:dat reg:reg, dat:nul ;
;; seg:reg, off:nul ;
;; seg:reg, adr:nul ;
;; seg:reg, dat:nul ;
;; ;
;; SATISFIED BY: ;
;; MOV dest_Right, WORD PTR source [0] ;
;; MOV dest_Left, WORD PTR source [2] ;
;;------------------------------------------------------------------------;
i INSTR <SRSO SRSA SRSD SRON SRAN SRDN RRSO RRSA RRSD RRON RRAN RRDN>, dest_source_tokens
IF (i)
i INSTR <DS ES>, dest_L
IF (i EQ 1)
LDS dest_R, source
ELSEIF (i EQ 4)
LES dest_R, source
ELSE
MOV dest_R, WORD PTR source [0]
MOV dest_L, WORD PTR source [2]
ENDIF
EXITM
ENDIF
;;------------------------------------------------------------------------;
;; display status of parsing process ;
;;------------------------------------------------------------------------;
.ERR MOVE &dest, &source is unparsable.
msg CATSTR <MOVE &dest, &source is unparsable. >, dest_source_tokens
DISPLAY %msg
ENDM
PAGE
;-----------------------------------------------------------------------------;
; Macro Name: RET_EMM_STATUS arg ;
; Author: W J Krueger ;
; Date: 4/10/89 ;
; Description: The value in AH (the current status of the EMM call) ;
; is converted to a word & returned to the caller. ;
;-----------------------------------------------------------------------------;
RET_EMM_STAT MACRO arg
MOV AL, arg
XOR AH, AH
RET
ENDM